//
// Created by XUAN on 2024/8/27.
//

#include "mqtt.h"

#include <audio_wrapper.h>
#include <circuit_board.h>
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include "esp_wifi.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_event.h"
#include "esp_netif.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#include "lwip/sockets.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"
#include "driver/rmt.h"
#include "cJSON.h"
#include "esp_log.h"
#include "mqtt_client.h"
#include <inttypes.h>
#include "audio_wrapper.h"
static const char *TAG = "MQTT_EXAMPLE";

/*--------------------------main-------------------------*/
extern char BT_MAC[35];
extern int msgId;
/*-------------------------------------------------------*/

/*--------------------------main-------------------------*/
extern QueueHandle_t mp3_url_queue;
/*-------------------------------------------------------*/

/*--------------------------parameters-----------------------*/

char sub_topic[50] = {0};
int answer_ID = 0;

extern char mqtt_server[60];
extern int mqtt_port;

bool sys_shutDown_state = false;

/*-----------------------------------------------------------*/



esp_mqtt_client_handle_t client;

// 处理 MQTT 数据
void handle_mqtt_data(const char *data, int data_len) {
    cJSON *root = cJSON_Parse(data);
    if (!root) {
        ESP_LOGE(TAG, "Failed to parse MQTT data");
        return;
    }
    // 根据不同命令执行操作
    if (cJSON_GetObjectItem(root, "cmd") != NULL) {
        cJSON *cmd = cJSON_GetObjectItem(root, "cmd");
        if (strcmp(cmd->valuestring, "text_to_speech") == 0) {
            if (strcmp(cJSON_GetObjectItem(root, "msg")->valuestring, "success") == 0){
                answer_ID = strtol(cJSON_GetObjectItem(root, "msgId")->valuestring, NULL, 10);

                if (atoi(cJSON_GetObjectItem(root, "msgId")->valuestring) == -1){
                    cJSON *data = cJSON_GetObjectItem(root, "data");
                    printf("data: %s\n", cJSON_Print(data));
                    if (cJSON_IsArray(data)) {
                        int size = cJSON_GetArraySize(data);
                        printf("data size: %d\n", size);
                        for (int i = 0; i < size; i++) {
                            cJSON *url = cJSON_GetArrayItem(data, i);
                            if (url != NULL) {
                                printf("Received URL: %s\n", url->valuestring);
                                chat_audio_player_play(url->valuestring);
                                ESP_LOGI(TAG, "Received URL: %s", url->valuestring);
                            }
                        }
                    }
                    else {
                        ESP_LOGE(TAG, "Data is not an array");
                        cJSON *url = cJSON_GetObjectItem(root, "data");
                        if (url != NULL) {
                            printf("Received URL: %s\n", url->valuestring);
                            chat_audio_player_play(url->valuestring);
                            ESP_LOGI(TAG, "Received URL: %s", url->valuestring);
                        }
                    }
                }

                if (atoi(cJSON_GetObjectItem(root, "msgId")->valuestring) != msgId){
                    return;
                }
                printf("Record ID: %d, Received answer ID: %d\n", msgId, answer_ID);
                cJSON *data = cJSON_GetObjectItem(root, "data");
                printf("data: %s\n", cJSON_Print(data));
                if (cJSON_IsArray(data)) {
                    int size = cJSON_GetArraySize(data);
                    printf("data size: %d\n", size);
                    for (int i = 0; i < size; i++) {
                        cJSON *url = cJSON_GetArrayItem(data, i);
                        if (url != NULL) {
                            printf("Received URL: %s\n", url->valuestring);
                            chat_audio_player_play(url->valuestring);
                            ESP_LOGI(TAG, "Received URL: %s", url->valuestring);
                        }
                    }
                }
                else {
                    ESP_LOGE(TAG, "Data is not an array");
                }
            }
        }
        else if (strcmp(cmd->valuestring, "multi_chat_config") == 0) {
            cJSON *msg = cJSON_GetObjectItem(root, "msg");
            if (msg != NULL && strcmp(msg->valuestring, "success") == 0) {
                cJSON *data = cJSON_GetObjectItem(root, "data");
                if (cJSON_IsObject(data)) {
                    cJSON *msgIdItem = cJSON_GetObjectItem(data, "msgId");
                    cJSON *wav_url = cJSON_GetObjectItem(data, "wav_url");
                    if (msgIdItem != NULL && wav_url != NULL) {
                        ESP_LOGI(TAG, "Received wav URL: %s, msgId: %d", wav_url->valuestring, msgIdItem->valueint);
                        // 在这里处理接收到的 wav_url
                    }
                }
            }
        }
        else if(strcmp(cmd->valuestring, "sys") == 0) {
            if (strcmp(cJSON_GetObjectItem(root, "data")->valuestring, "shutup") == 0)
            {
               chat_shutup();
                ESP_LOGI(TAG, "shutup!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
            }
            if (strcmp(cJSON_GetObjectItem(root, "data")->valuestring, "shutdown") == 0)
            {
                sys_shutDown_state = true;
                circuit_board_ShutDown();
                ESP_LOGI(TAG, "shutdown power");
            }
        }
    }
    else {
        // ESP_LOGE(TAG, "Unknown command: %s", cmd->valuestring);
        ESP_LOGE(TAG, "Unknown command");
    }
    cJSON_Delete(root);
}


// MQTT 事件处理
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) {
    esp_mqtt_event_handle_t event = event_data;
    client = event->client;
    int msg_id;

    switch ((esp_mqtt_event_id_t)event_id) {
        case MQTT_EVENT_CONNECTED:
            ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
            sprintf(sub_topic, "paho/test/%s", BT_MAC);
            ESP_LOGI(TAG, "Attempting to subscribe to topic: %s", sub_topic);
            msg_id = esp_mqtt_client_subscribe(client, sub_topic, 0);
            ESP_LOGI(TAG, "Subscribed to topic with msg_id=%d", msg_id);
            break;
        case MQTT_EVENT_DATA:
            ESP_LOGI(TAG, "MQTT_EVENT_DATA received");
            printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
            printf("DATA=%.*s\r\n", event->data_len, event->data);
            // 处理收到的数据，根据不同命令执行不同操作
            handle_mqtt_data(event->data, event->data_len);
            break;
        case MQTT_EVENT_DISCONNECTED:
            ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
            break;
        case MQTT_EVENT_SUBSCRIBED:
            ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
            break;
        case MQTT_EVENT_UNSUBSCRIBED:
            ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
            break;
        case MQTT_EVENT_PUBLISHED:
            ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
            break;
        case MQTT_EVENT_ERROR:
            ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
            if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) {
                ESP_LOGI(TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno));
                ESP_LOGI(TAG, "TLS stack error: 0x%x", event->error_handle->esp_tls_stack_err);
                ESP_LOGI(TAG, "Last ESP error: 0x%x", event->error_handle->esp_tls_last_esp_err);
            }
            break;
        default:
            ESP_LOGI(TAG, "Other event id:%d", event->event_id);
            break;
    }
}

// 开始 MQTT 连接
void mqtt_app_start(void)
{
    while (mqtt_server[0] == 0)
    {
        vTaskDelay(150);
    }

    ESP_LOGI(TAG, "Initializing MQTT client with server: %s, port: %d", mqtt_server, mqtt_port);

    char *mqtt_uri;
    mqtt_uri = (char *)heap_caps_malloc(100 * sizeof(uint8_t), MALLOC_CAP_SPIRAM);
    sprintf(mqtt_uri, "mqtt://%s", mqtt_server);

    esp_mqtt_client_config_t mqtt_cfg = {
            .broker = {
                    .address.uri = mqtt_uri,
                    .address.port = mqtt_port,
            },
            .session = {
                    .disable_clean_session = false, // 设置为 false，确保每次连接时会话状态被清理
                    .keepalive = 120,  // Keepalive 时间为 120 秒
            },
            .network = {
                    .reconnect_timeout_ms = 10000,  // 重连超时为 10 秒
            },
            .task = {
                    .priority = 5,  // MQTT 任务优先级
                    .stack_size = 4096,  // MQTT 任务堆栈大小
            },
    };

    ESP_LOGI(TAG, "MQTT URI: %s", mqtt_uri);

    esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);

    if (client == NULL) {
        ESP_LOGE(TAG, "Failed to initialize MQTT client");
        heap_caps_free(mqtt_uri);
        return;
    }

    esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);

    esp_err_t err = esp_mqtt_client_start(client);
    if (err != ESP_OK) {
        ESP_LOGE(TAG, "Failed to start MQTT client: %s", esp_err_to_name(err));
    } else {
        ESP_LOGI(TAG, "MQTT client started successfully");
    }

    heap_caps_free(mqtt_uri);

}












